/*
 * @(#)XfvhdlVectorCount.java        3.0                      2004/09/14
 *
 * This file is part of Xfuzzy 3.0, a design environment for fuzzy logic
 * based systems.
 *
 * (c) 2000 IMSE-CNM. The authors may be contacted by the email address:
 *                    xfuzzy-team@imse.cnm.es
 *
 * Xfuzzy is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by
 * the Free Software Foundation.
 *
 * Xfuzzy is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

package xfuzzy.xfvhdl;

/**
* Esta clase es un contador especial para recorrer la memoria de reglas.
* @author Jos� Mar�a �vila Maireles, <b>e-mail</b>: josavimai@alum.us.es
* @version 3.0
*/
public class XfvhdlVectorCount {

   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   //		  ATRIBUTOS DE LA CLASE 				       
   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   private int lengh;
   private int vector[];
   private int max;
   private int initial[];
   private int lengh_real;
   private boolean valid;

   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   //				  CONSTRUCTOR DE LA CLASE					   
   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   /**
    * Constructor de XVectorCount.
    * @param lengh Longitud del vector.
    * @param valor Valor m�ximo que tendran las casillas del vector.
    * @param initial[] Valores iniciales de las casillas del vector.
    */
   public XfvhdlVectorCount(int lengh, int valor, int initial[]) {

      // miro si todas las variables tienen una funci�n miembro 
      // asociada
      boolean n = false;
      for (int ii = 0; ii < initial.length && !n; ii++) {
         if (initial[ii] == -1)
            n = true;
      }

      // indico si el vector se puede restar o no
      if (!n)
         valid = false;
      else
         valid = true;

      lengh_real = lengh;

      int tmp = 0;
      for (int j = 0; j < initial.length; j++) {
         if (initial[j] == -1)
            tmp++;
      }

      this.lengh = tmp;

      vector = new int[this.lengh];
      max = valor;

      this.initial = initial;
      for (int i = 0; i < this.lengh; i++) {
         vector[i] = max;
      }
   }

   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   //			M�TO_DOS P�BLICOS DE LA CLASE				        
   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   /**
    * M�todo para obtener el valor de la posici�n pos del vector.
    * @param pos Posici�n del vector que deseamos conocer.
    * @return Valor que contiene el vector en la posici�n pos.
    */
   public int get(int pos) {
      int res;
      int tmp = 0;
      int l = 0;

      if (initial[pos] != -1)
         res = initial[pos];
      else {
         while (l < pos) {
            if (initial[l] == -1)
               tmp++;
            l++;
         }
         res = max - vector[tmp];
      }
      return res;
   }

   /**
    * M�todo que resta un elemento en el vector. 
    * @return Devuelve un booleano indicando si se realiz� la operaci�n
    * con �xito o no. 
    */
   public boolean sub() {
      boolean d = true;
      boolean dec = false;
      boolean cont = true;
      int actual = lengh - 1;

      if (!valid)
         return valid;

      if (vector[actual] > 0) {
         sub(actual);
      } else {
         while (!dec && actual >= 0) {

            if (actual > 0) {
               actual--;
            } else {
               cont = false;
               dec = true;
               d = false;
            }

            if (cont) {

               if (vector[actual] == 0) {
               } else {
                  sub(actual);
                  dec = true;
                  reset(actual + 1);

               }
            }
         }
      }

      return d;
   }

   /**
    * M�todo para imprimir por pantalla el valor actual del vector.
    * S�lo tiene utilidad este m�todo para la depuraci�n de esta clase.
    */
   public void print() {
      String cadena = new String("[ ");

      for (int i = 0; i < lengh_real; i++) {
         cadena += get(i) + " ";
      }

      cadena += "]";
      System.out.println("El vector va por: " + cadena);
   }

   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   //			  M�TO_DOS PRIVADOS DE LA CLASE				        
   //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
   /**
    * M�todo que decrementa el vector en la posici�n pos.
    */
   private boolean sub(int pos) {
      boolean d = true;

      if (vector[pos] > 0)
         vector[pos]--;
      else
         d = false;

      return d;
   }

   /**
    * M�todo que resetea el vector en su posici�n pos.
    */
   private void reset(int pos) {
      for (int i = pos; i < lengh; i++) {
         vector[i] = max;
      }
   }

}
